package com.company.clientscard.server.dao;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.Query;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public abstract class UniversalDao<T, E extends Serializable> extends
		HibernateDaoSupport implements GenericDao<T, E> {

	private Class<T> type;

	protected UniversalDao(Class<T> type) {
		this.type = type;
	}

	protected UniversalDao() {
	}

	@Override
	public T findById(T type, E id) {
		return (T) getSession().get((Class<T>) type, id);
	}

	public void save(T entity) {
		getSession().save(entity);
	}

	public void update(E entity) {
		getSession().saveOrUpdate(entity);
	}

	@Override
	public List<T> findAll(Class<T> type) {
		return getSession().createQuery("from " + type.getName()).list();
	}

	public List<T> findAll(Class<T> type, int firstRow, int numberOfRows) {
		Query query = getSession().createQuery("from " + type.getName());
		query.setFirstResult(firstRow);
		query.setMaxResults(numberOfRows);

		return query.list();
	}

	public List<T> findWithExpression(Class<T> type, int firstRow,
			int numberOfRows, Date date1, Date date2) {

		if (date1 == null || date2 == null) {
			return findAll(type, firstRow, numberOfRows);
		} else {
			Query query = getSession()
					.createQuery(
							"from "
									+ type.getName()
									+ " table1 WHERE table1.docDate between :date1 and :date2");
			query.setParameter("date1", date1);
			query.setParameter("date2", date2);
			query.setFirstResult(firstRow);
			query.setMaxResults(numberOfRows);

			return query.list();
		}
	}

	public List<T> findWithParam(Class<T> type, String paramName, Object param) {

		if (param == null || paramName == null || paramName == null) {
			return new ArrayList<T>();
		} else {
			Query query = getSession().createQuery(
					"from " + type.getName() + " table1 WHERE table1."
							+ paramName + " = :param");
			query.setParameter("param", param);

			return query.list();
		}
	}

}
